package com.kitty.game.fight.bean;

import com.kitty.common.utils.SpringUtils;
import com.kitty.common.utils.PositionUtils;
import com.kitty.game.child.model.ChildInfo;
import com.kitty.game.enter.FiedValue;
import com.kitty.game.fight.message.vo.FightMember;
import com.kitty.game.fight.message.vo.SkillGroup;
import com.kitty.game.fight.service.CountService;
import com.kitty.game.fight.util.FightRateUtil;
import com.kitty.game.fuling.model.Fuling;
import com.kitty.game.role.model.Role;
import com.kitty.game.skill.model.RoleSkill;
import com.kitty.game.utils.Const;
import com.kitty.game.utils.StringUtil;
import com.kitty.game.waiguan.CustomFasionIcon;
import com.kitty.mina.cache.DataCache;
import com.kitty.mina.cache.SessionUtils;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.mina.core.session.IoSession;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
public class PlayerFightObject extends FightObject {

    private static final NutMap publicAutoSet = NutMap.NEW();

    @Getter
    private Role role;

    @Getter
    private int index;

    @Getter
    private int customIndex;

    /**是否使用月道行计算*/
    @Getter
    @Setter
    private boolean useMonthTao;

    /**
     * 当前生效的法宝
     */
    private String equppedFabao;

    static {
        publicAutoSet.setv("type", 2);
        publicAutoSet.setv("action", 1);
        publicAutoSet.setv("skillId", 2);
        publicAutoSet.setv("multi", 0);
        publicAutoSet.setv("list", new ArrayList<>());
    }

    public PlayerFightObject(Role role, int index, int customIndex, boolean isA) {
        this.index = index;
        this.customIndex = customIndex;
        this.role = role;
        Map<String, Object> autoSet = role.getExtendBox().getAutoFightSet();
        if (autoSet == null || autoSet.size() <= 0) {
            autoSet = publicAutoSet;
        }
        setName(role.getName());
        setFightMsg(role.getShouts());
        setLevel(role.getLevel());
        setId(role.getRoleId());
        setDefense(role.getMaxDefense());
        setSpeed(role.getMaxSpeed());
        setMagPower(role.getMaxMagPower());
        setPhyPower(role.getMaxPhyPower());
        setMaxLife(role.getMaxLife());
        setMaxMana(role.getMaxMana());
        setCurrMana(role.getCurrMana());
        setCurrLife(role.getCurrLife());
        this.role = role;
        setAutoFight(role.getAutoFight());
        setAutoSkillId((Integer) autoSet.get("skillId"));
        setSkillId((Integer) autoSet.get("skillId"));
        setType((Integer) autoSet.get("type"));
        setMultiIndex(((Integer) autoSet.get("multi")).byteValue());
        setAutoFightType((Integer) autoSet.get("type"));
        setAction(((Integer) autoSet.get("action")).byteValue());
        setSkillGroups((List<SkillGroup>) autoSet.get("list"));
        setFightPetId(role.getPetBox().getFightPetId());
        setIcon(role.getRoleIcon());
        setPolar(role.getPolar());
        setASide(isA);
        setWeaponId(role.getWeaponIcon());
        setPos(PositionUtils.positions.get(index));
        setSuitIcon(role.getSuitId());
        setChangeCard(role.getChangeCard());

        Fuling fuling = SpringUtils.getFulingService().getFulingdata(role.getRoleId());
        if(fuling!=null){
            setFulingtype(fuling.getType1());
            if(fuling.getType1()==1){
                setFulingdengji(fuling.getQinglong());
            }else if(fuling.getType1()==2){
                setFulingdengji(fuling.getZhuque());
            }else if(fuling.getType1()==3){
                setFulingdengji(fuling.getBaihu());
            }else if(fuling.getType1()==4){
                setFulingdengji(fuling.getXuanwu());
            }
        }


        this.equppedFabao = SpringUtils.getArtifactService().getEquippedArtifact(role);

        // 亲密无间技能
        SpringUtils.getFightService().sendQiMiSkills(role, role.getPetBox().getFightPetId());
    }

    @Override
    public RoleSkill getSkillBy(int skillId) {
        return SpringUtils.getSkillService().getRoleSkill(getRole(), getFightPetId(), skillId);
    }

    private int getFasionIcon(){
        ChildInfo childInfo = role.getChildInfo();
        if (childInfo != null && childInfo.getState() != 0){
            if (childInfo.getType() ==1 ){
                return 7008;
            }else if (childInfo.getType() ==2 ){
                return 7009;
            }
        }
        return role.getFasionIcon() > 0 ? role.getFasionIcon() : role.getShapePen() != null ? role.getShapePen().getIcon() : role.getChangeCard() != null ? role.getChangeCard().getIcon() : 0;
    }

    @Override
    public FightMember asFightMember(List<CustomFasionIcon> customIconList) {
        FightMember fightMember = new FightMember();
        fightMember.setId(getId());
        fightMember.setSpecial_icon(getFasionIcon());//战斗加载时装
        if (role.isCustom()) {
            customIconList.get(customIndex).setCustomFasionIcon(role.getCustomFasion());
            if (!Strings.isEmpty(role.getCustomFasion())) {
                if (role.getGender() == 1) {
                    fightMember.setSpecial_icon(61001);//战斗加载时装
                } else {
                    fightMember.setSpecial_icon(60001);//战斗加载时装
                }
            }
        }
        fightMember.setWeapon_icon((short) getWeaponId());
        fightMember.setSuit_light_effect(role.getSuitLightId() <= 7000 || role.getSuitLightId() >= 7006 ? 0 : role.getSuitLightId());
        if (role.isVip()) {
            fightMember.setVipStatus((short) role.getVipType());
        }
        fightMember.setSuit_icon(getSuitIcon());
        fightMember.setPosition((short) getPos());
        fightMember.setIcon((short) getIcon());
        fightMember.setList(asFieldValues());
        return fightMember;
    }


    @Override
    public List<FiedValue> asFieldValues() {
        ArrayList<FiedValue> fiedValues = new ArrayList<>();
        fiedValues.add(new FiedValue(1, 4, getName()));
        fiedValues.add(new FiedValue(40, 7, getIcon()));
        fiedValues.add(new FiedValue(41, 7, (short) 1));
        fiedValues.add(new FiedValue(204, 3, 0));
        fiedValues.add(new FiedValue(341, 1, (byte) 0));
        fiedValues.add(new FiedValue(340, 1, (byte) 0));
        fiedValues.add(new FiedValue(12, 3, getMaxMana()));
        fiedValues.add(new FiedValue(11, 3, getCurrMana()));
        fiedValues.add(new FiedValue(6, 3, getCurrLife()));
        fiedValues.add(new FiedValue(7, 3, getMaxLife()));

        fiedValues.add(new FiedValue(1005, 3,  getFulingtype()));
        fiedValues.add(new FiedValue(1006, 3,  getFulingdengji()));
        return fiedValues;
    }

    /**
     * 取破防
     */
    private double getPenetrate() {
        double penetrate = role.getPenetrate() / 100.0;
        if (penetrate > 0.6) {
            penetrate = 0.6;
        } else if (penetrate < 0) {
            penetrate = 0.0;
        }
        return penetrate;
    }

    @Override
    public int getMagHurt(FightObject target, boolean isPenetrate) {
        RoleSkill roleSkill = getSkillBy(getSkillId());
        double penetrate = 0.0;
        double per = 0.0009;
        boolean isRestraint = isRestraint(target);// 五行相克
        int targetResist = getTargetResistValue(target);//抗性
        byte skillRank = roleSkill.getSkillJieshu();
        if (skillRank == 2) {
            per = 0.001;
        } else if (skillRank == 3) {
            per = 0.002;
        } else if (skillRank == 4) {
            per = 0.004;
        } else if (skillRank == 5) {
            per = 0.003;
        }
        if (isPenetrate) {
            penetrate = getPenetrate();
        }
        double absorb = targetResist - getIgnoreResist();//这里还要加一个变身卡的抵抗法术
        absorb /= 100.0;
        absorb = Math.max(absorb, 0);
        //伤害加成
        double hurtAddition = 0.0;
        hurtAddition += role.getChildInfo().getMo()*0.004;

        int totalWiz = role.getWiz() + role.getExtendBox().getBasicAttrib().getWiz() + role.getExtraWiz();
        int totalMetal = role.getMetal() + role.getExtraMetal();
        double rate = 0.69;
        String magRate = DataCache.REDIS_DATA.get("mag_rate");
        if(!StringUtil.isEmpty(magRate)){
            rate = Double.parseDouble(magRate);
        }
        Double result = ((((totalWiz * (totalMetal + getCurrPolar() / 2.5) *rate) + totalWiz * 5 + 40)
                + role.getExtraMagPower()) * (1 + role.getExtraStrengthMagRate() / 100.0)
                * (1.0 + ((roleSkill.getLevel() + role.getExtraSkillLevel()) * per)) + getExtraAttack()
                + FightRateUtil.getRandHurt(this.getMagPower())) * (1.0 - absorb)
                - ((1.0 - penetrate) * (target.getDefense() + target.getExtraDefense()))
                * (1.0 + hurtAddition);
        //这里修复仙道点的减伤
        result =(double)CountService.getHurtByReduce(result.intValue(),target,true);
        /**五行相克*/
        if (isRestraint) {
            result = result * 1.2;
        }
        if (target.getXinjun() != null) {
            result = countAbsorb(this.getRole().getId(), result, target.getXinjun().getMag_absorb());
        }
        return result.intValue();
    }

    @Override
    public int getPhyHurt(FightObject target, boolean isPenetrate) {
        RoleSkill roleSkill = getSkillBy(getSkillId());
        int skillLevel = 0;
        if (roleSkill != null && roleSkill.getSkillId() == 501) {
            skillLevel = roleSkill.getLevel() + role.getExtraSkillLevel();
        }
        double penetrate = 0.0;
        if (isPenetrate) {
            penetrate = getPenetrate();
        }
        //伤害加成
        double hurtAddition = 0.0;
        hurtAddition += role.getChildInfo().getMo()*0.004;
        int totalStr = role.getStr() + role.getExtendBox().getBasicAttrib().getStr() + role.getExtraStr();
        int totalEarth = role.getEarth() + role.getExtraEarth();
        double rate = 1.75;
        String phyRate = DataCache.REDIS_DATA.get("phy_rate");
        if(!StringUtil.isEmpty(phyRate)){
            rate = Double.parseDouble(phyRate);
        }

        Double result = ((((totalStr * totalEarth * rate) + totalStr * 5 + 40)
                + role.getExtraPhyPower()) * (1 + role.getExtraStrengthPhyRate() / 100.0)
                * (1.0 + (skillLevel * 0.003)) + getExtraAttack()
                + FightRateUtil.getRandHurt(this.getPhyPower()))
                - ((1.0 - penetrate) * (target.getDefense() + target.getExtraDefense()))
                * (1.0 + hurtAddition);

        //这里修复仙道点的减伤
        result =(double)CountService.getHurtByReduce(result.intValue(),target,true);
        /**计算星君的抵抗*/
        if (target.getXinjun() != null) {
            result = countAbsorb(this.getRole().getId(), result, target.getXinjun().getPhy_absorb());
        }
        if (target.getId() != targetId) {
            result /= 2;/**如果是力魄 但是目标不是主目标 伤害只有一半*/
        }
        return result.intValue();
    }

    /**
     * 取本系的相性点
     */
    private int getCurrPolar() {
        int currPolar = 0;
        short polar = this.getPolar();
        if (polar == Const.SCHOOL_METAL) {
            currPolar = this.isPlayer() ? this.getRole().getMetal() + this.getRole().getExtraMetal() : 1;
        } else if (polar == Const.SCHOOL_WOOD) {
            currPolar = this.isPlayer() ? this.getRole().getWood() + this.getRole().getExtraWood() : 1;
        } else if (polar == Const.SCHOOL_WATER) {
            currPolar = this.isPlayer() ? this.getRole().getWater() + this.getRole().getExtraWater() : 1;
        } else if (polar == Const.SCHOOL_FIRE) {
            currPolar = this.isPlayer() ? this.getRole().getFire() + this.getRole().getExtraFire() : 1;
        } else if (polar == Const.SCHOOL_EARTH) {
            currPolar = this.isPlayer() ? this.getRole().getEarth() + this.getRole().getExtraEarth() : 1;
        }
        return currPolar;
    }


    /**
     * 取忽视目标抗性
     */
    private int getIgnoreResist() {
        int ignoreResist = 0;
        if (this.getPolar() == Const.SCHOOL_METAL) {
            ignoreResist = this.isPlayer() ? this.getRole().getIgnoreResistMetal() : 0;
        } else if (this.getPolar() == Const.SCHOOL_WOOD) {
            ignoreResist = this.isPlayer() ? this.getRole().getIgnoreResistWood() : 0;
        } else if (this.getPolar() == Const.SCHOOL_WATER) {
            ignoreResist = this.isPlayer() ? this.getRole().getIgnoreResistWater() : 0;
        } else if (this.getPolar() == Const.SCHOOL_FIRE) {
            ignoreResist = this.isPlayer() ? this.getRole().getIgnoreResistFire() : 0;
        } else if (this.getPolar() == Const.SCHOOL_EARTH) {
            ignoreResist = this.isPlayer() ? this.getRole().getIgnoreResistEarth() : 0;
        }
        return ignoreResist;
    }

    @Override
    public int getTao() {
        if (useMonthTao) {
            return role.getMonthTao();
        }

        return role.getTao();
    }

    @Override
    public IoSession getSession() {
        return SessionUtils.getSessionBy(this.getRole().getId());
    }

    @Override
    public String toString() {
        return "PlayerFightObject{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
